package org.example.project.bookstore.service.impl;

import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.example.bean.Book;
import org.example.bean.shopping;
import org.example.config.JwtConfig;
import org.example.mapper.BookMapper;
import org.example.mapper.shoppingMapper;
import org.example.project.bookstore.service.ShoppingCartService;
import org.example.util.JsonResult;
import org.example.util.ResultTool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.NumberFormat;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Auther:Liu
 * @Testname:ShoppingCartServiceImpl
 * @Date:2025/8/19 17:53
 */
@Slf4j
@Service
public class ShoppingCartServiceImpl implements ShoppingCartService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    public static final String SHOPPING_CART = "shopping_cart";
    @Autowired
    private BookMapper bookMapper;

    /**
     * 在购物车中添加书
     *
     * @param bookId
     * @param token
     * @return
     */
//    @CacheEvict(cacheNames = "findBookByCateGory", allEntries = true)
    @CacheEvict(cacheNames = "findCartByUserId", key = "#token")
    public JsonResult addBook(String bookId, String token) {
        Claims claims = JwtConfig.parseJWT(token);
        String userId = claims.get("id").toString();
        HashOperations<String, String, String> ops = stringRedisTemplate.opsForHash();
        Map<String, String> stringMap = ops.entries(SHOPPING_CART + userId);
        if (stringMap.isEmpty()) {
            ops.put(SHOPPING_CART + userId, bookId, "1");
            return ResultTool.success("success");
        }
        //判断商品是否在购物车里
        boolean b = stringMap.containsKey(bookId);
        if (b) {
            ops.increment(SHOPPING_CART + userId, bookId, 1);
        } else {
            stringMap.put(bookId, "1");
            ops.putAll(SHOPPING_CART + userId, stringMap);
        }
        return ResultTool.success("success");
    }

    /**
     * 根据UserId获取购物车信息,设置属性信息
     *
     * @param request
     * @return
     */
    @Cacheable(cacheNames = "findCartByUserId",key = "#request.getHeader('token')")
    public JsonResult findCartByUserId(HttpServletRequest request) {
        // 1.0. 根据令牌获取UserId,获取购物车
        String token = request.getHeader("token");
        Claims claims = JwtConfig.parseJWT(token);
        String userId = claims.get("id").toString();
        HashOperations<String, String, String> ops = stringRedisTemplate.opsForHash();
        Map<String, String> stringMap = ops.entries(SHOPPING_CART + userId);
        // 2.0. 遍历购物车的信息，设置折扣价
        Set<String> set = stringMap.keySet();
        List<Book> list = bookMapper.findBookByBookId(set);
        for (Book book : list) {
            if (book.getDiscountRate() == null) {
                book.setDiscountPrice(book.getPrice());
            } else {
                NumberFormat instance = NumberFormat.getInstance();
                instance.setMaximumFractionDigits(2);
                String format = instance.format(book.getDiscountRate() * book.getPrice());
                book.setDiscountPrice(Double.valueOf(format));
            }
            String s = stringMap.get(book.getId());
            book.setBookNumber(Integer.valueOf(s));
        }
        return ResultTool.success(list);
    }

    /**
     * 增删购物车书本数量
     * @param bookId
     * @param token
     * @return
     */
    @CacheEvict(cacheNames = "findCartByUserId", key = "#token")
    public JsonResult incrementOrDeleteBookNumber(String bookId,Integer number, String token) {
        Claims claims = JwtConfig.parseJWT(token);
        String userId = claims.get("id").toString();
        HashOperations<String, String, String> ops = stringRedisTemplate.opsForHash();
        if (number==null){
            return ResultTool.fail(200,"number不能为空");
        }else if (number==1){
            ops.increment(SHOPPING_CART + userId, bookId, 1);
        } else if (number==-1) {
            ops.increment(SHOPPING_CART + userId, bookId, -1);
        }
        return ResultTool.success("success");
    }

    @CacheEvict(cacheNames = "findCartByUserId", key = "#token")
    public JsonResult updateBookNumber(String bookId, Integer number, String token) {
        Claims claims = JwtConfig.parseJWT(token);
        String userId = claims.get("id").toString();
        HashOperations<String, String, String> ops = stringRedisTemplate.opsForHash();
        if (number==null){
            return ResultTool.fail(200,"number不能为空");
        }else  {
            ops.put(SHOPPING_CART + userId, bookId, String.valueOf(number));
        }
        return ResultTool.success("success");
    }

    /**
     * 删除购物车单个书本
     * @param bookId
     * @param token
     * @return
     */
    @CacheEvict(cacheNames = "findCartByUserId", key = "#token")
    public JsonResult deleteBook(String bookId, String token) {
        Claims claims = JwtConfig.parseJWT(token);
        String userId = claims.get("id").toString();
        HashOperations<String, String, String> ops = stringRedisTemplate.opsForHash();
        ops.delete(SHOPPING_CART + userId, bookId);
        return ResultTool.success("success");
    }

    /**
     * 删除多个购物车书本
     * @param bookIds
     * @param token
     * @return
     */
    @CacheEvict(cacheNames = "findCartByUserId", key = "#token")
    public JsonResult deleteMoreBook(String[] bookIds, String token) {
        Claims claims = JwtConfig.parseJWT(token);
        String userId = claims.get("id").toString();
        HashOperations<String, String, String> ops = stringRedisTemplate.opsForHash();
        ops.delete(SHOPPING_CART + userId, bookIds);
        return ResultTool.success("success");
    }

    @Resource
    private shoppingMapper shoppingMapper;
    /**
     * 备份数据
     * @return
     */
    @Transactional
    @Scheduled(cron = "0 39 15 * * *")
    public void updateAllBook() {
        log.info("开始删除");
        // 1.0. 清空购物车
        shoppingMapper.deleteAll();
        //2.0. 获取购物车信息
        HashOperations<String, String, String> ops = stringRedisTemplate.opsForHash();
        Set<String> keys = stringRedisTemplate.keys(SHOPPING_CART+"*");
        log.info("keys:" + keys);
        for (String key : keys) {
            String newKey=key;
            log.info("newKey:"+newKey);
            String s = newKey.replaceAll(SHOPPING_CART, "");
            Map<String, String> stringMap = ops.entries(SHOPPING_CART + s);
            Set<String> set = stringMap.keySet();
            for (String bookId : set) {
                log.info("bookId:"+bookId);
                String number = ops.get(newKey, bookId);
                shopping shopping = new shopping();
                shopping.setBookId(bookId);
                shopping.setNumber(Integer.valueOf(number));
                shopping.setUserId(s);
                shoppingMapper.insert(shopping);
            }
        }
    }


}
